//////////////////////////////////////////ok
#include"stdafx.h"
#include "bochs.h"


void IA32_CPU::XOR_EwGw(Ia32_Instruction_c *i)
{
  Bit16u op2_16, op1_16, result_16;
  op2_16 = IA32_READ_16BIT_REG(i->nnn());
  if (i->modC0()) 
  {
    op1_16 = IA32_READ_16BIT_REG(i->rm());
#if defined(IA32_HostAsm_Xor16)
    Bit32u flags32;
    asmXor16(result_16, op1_16, op2_16, flags32);
    IA32_setEFlagsOSZAPC(flags32);
#else
    result_16 = op1_16 ^ op2_16;
#endif
    IA32_WRITE_16BIT_REG(i->rm(), result_16);
  }
  else 
  {
    read_RMW_virtual_word(i->seg(), IA32_RMAddr(i), &op1_16);
#if defined(IA32_HostAsm_Xor16)
    Bit32u flags32;
    asmXor16(result_16, op1_16, op2_16, flags32);
    IA32_setEFlagsOSZAPC(flags32);
#else
    result_16 = op1_16 ^ op2_16;
#endif
    write_RMW_virtual_word(result_16);
  }
#if !defined(IA32_HostAsm_Xor16)
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);
#endif
}

void IA32_CPU::XOR_GwEw(Ia32_Instruction_c *i)
{
  Bit16u op1_16, op2_16, result_16;
  unsigned nnn = i->nnn();

  op1_16 = IA32_READ_16BIT_REG(nnn);
  if (i->modC0()) 
  {
    op2_16 = IA32_READ_16BIT_REG(i->rm());
  }
  else 
  {
    read_virtual_word(i->seg(), IA32_RMAddr(i), &op2_16);
  }

  result_16 = op1_16 ^ op2_16;
  IA32_WRITE_16BIT_REG(nnn, result_16);
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);
}

void IA32_CPU::XOR_AXIw(Ia32_Instruction_c *i)
{
  Bit16u op1_16, op2_16, sum_16;

  op1_16 = AX;
  op2_16 = i->Iw();
  sum_16 = op1_16 ^ op2_16;
  AX = sum_16;
  IA32_SET_FLAGS_OSZAPC_RESULT_16(sum_16, IA32_INSTR_LOGIC16);
}

void IA32_CPU::XOR_EwIw(Ia32_Instruction_c *i)
{
  Bit16u op2_16, op1_16, result_16;

  op2_16 = i->Iw();
  if (i->modC0()) 
  {
    op1_16 = IA32_READ_16BIT_REG(i->rm());
    result_16 = op1_16 ^ op2_16;
    IA32_WRITE_16BIT_REG(i->rm(), result_16);
  }
  else 
  {
    read_RMW_virtual_word(i->seg(), IA32_RMAddr(i), &op1_16);
    result_16 = op1_16 ^ op2_16;
    write_RMW_virtual_word(result_16);
  }
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);

}

void IA32_CPU::OR_EwIw(Ia32_Instruction_c *i)
{
  Bit16u op2_16, op1_16, result_16;

  op2_16 = i->Iw();
  if (i->modC0()) 
  {
    op1_16 = IA32_READ_16BIT_REG(i->rm());
    result_16 = op1_16 | op2_16;
    IA32_WRITE_16BIT_REG(i->rm(), result_16);
  }
  else 
  {
    read_RMW_virtual_word(i->seg(), IA32_RMAddr(i), &op1_16);
    result_16 = op1_16 | op2_16;
    write_RMW_virtual_word(result_16);
  }
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);

}

void IA32_CPU::NOT_Ew(Ia32_Instruction_c *i)
{
  Bit16u op1_16, result_16;

  if (i->modC0()) 
  {
    op1_16 = IA32_READ_16BIT_REG(i->rm());
    result_16 = ~op1_16;
    IA32_WRITE_16BIT_REG(i->rm(), result_16);
  }
  else 
  {
    read_RMW_virtual_word(i->seg(), IA32_RMAddr(i), &op1_16);
    result_16 = ~op1_16;
    write_RMW_virtual_word(result_16);
  }
}

void IA32_CPU::OR_EwGw(Ia32_Instruction_c *i)
{
  Bit16u op2_16, op1_16, result_16;

  op2_16 = IA32_READ_16BIT_REG(i->nnn());
  if (i->modC0()) 
  {
    op1_16 = IA32_READ_16BIT_REG(i->rm());
    result_16 = op1_16 | op2_16;
    IA32_WRITE_16BIT_REG(i->rm(), result_16);
  }
  else 
  {
    read_RMW_virtual_word(i->seg(), IA32_RMAddr(i), &op1_16);
    result_16 = op1_16 | op2_16;
    write_RMW_virtual_word(result_16);
  }
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);
}

void IA32_CPU::OR_GwEw(Ia32_Instruction_c *i)
{
  Bit16u op1_16, op2_16, result_16;

  op1_16 = IA32_READ_16BIT_REG(i->nnn());
  if (i->modC0()) 
  {
    op2_16 = IA32_READ_16BIT_REG(i->rm());
  }
  else 
  {
    read_virtual_word(i->seg(), IA32_RMAddr(i), &op2_16);
  }

#if defined(IA32_HostAsm_Or16)
  Bit32u flags32;
  asmOr16(result_16, op1_16, op2_16, flags32);
  IA32_setEFlagsOSZAPC(flags32);
#else
  result_16 = op1_16 | op2_16;
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);
#endif
  IA32_WRITE_16BIT_REG(i->nnn(), result_16);
}

void IA32_CPU::OR_AXIw(Ia32_Instruction_c *i)
{
  Bit16u op1_16, op2_16, sum_16;

  op1_16 = AX;
  op2_16 = i->Iw();
  sum_16 = op1_16 | op2_16;
  AX = sum_16;
  IA32_SET_FLAGS_OSZAPC_RESULT_16(sum_16, IA32_INSTR_LOGIC16);
}

void IA32_CPU::AND_EwGw(Ia32_Instruction_c *i)
{
  Bit16u op2_16, op1_16, result_16;

  op2_16 = IA32_READ_16BIT_REG(i->nnn());
  if (i->modC0()) 
  {
    op1_16 = IA32_READ_16BIT_REG(i->rm());
#if defined(IA32_HostAsm_And16)
    Bit32u flags32;
    asmAnd16(result_16, op1_16, op2_16, flags32);
    IA32_setEFlagsOSZAPC(flags32);
#else
    result_16 = op1_16 & op2_16;
#endif
    IA32_WRITE_16BIT_REG(i->rm(), result_16);
  }
  else 
  {
    read_RMW_virtual_word(i->seg(), IA32_RMAddr(i), &op1_16);
#if defined(IA32_HostAsm_And16)
    Bit32u flags32;
    asmAnd16(result_16, op1_16, op2_16, flags32);
    IA32_setEFlagsOSZAPC(flags32);
#else
    result_16 = op1_16 & op2_16;
#endif
    write_RMW_virtual_word(result_16);
  }

#if !defined(IA32_HostAsm_And16)
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);
#endif
}

void IA32_CPU::AND_GwEw(Ia32_Instruction_c *i)
{
  Bit16u op1_16, op2_16, result_16;

  op1_16 = IA32_READ_16BIT_REG(i->nnn());
  if (i->modC0()) 
  {
    op2_16 = IA32_READ_16BIT_REG(i->rm());
  }
  else 
  {
    read_virtual_word(i->seg(), IA32_RMAddr(i), &op2_16);
  }

#if defined(IA32_HostAsm_And16)
  Bit32u flags32;
  asmAnd16(result_16, op1_16, op2_16, flags32);
  IA32_setEFlagsOSZAPC(flags32);
#else
  result_16 = op1_16 & op2_16;
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);
#endif
  IA32_WRITE_16BIT_REG(i->nnn(), result_16);
}

void IA32_CPU::AND_AXIw(Ia32_Instruction_c *i)
{
  Bit16u op1_16, op2_16, result_16;

  op1_16 = AX;
  op2_16 = i->Iw();
#if defined(IA32_HostAsm_And16)
  Bit32u flags32;
  asmAnd16(result_16, op1_16, op2_16, flags32);
  IA32_setEFlagsOSZAPC(flags32);
#else
  result_16 = op1_16 & op2_16;
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);
#endif
  AX = result_16;
}

void IA32_CPU::AND_EwIw(Ia32_Instruction_c *i)
{
  Bit16u op2_16, op1_16, result_16;

  op2_16 = i->Iw();
  if (i->modC0()) 
  {
    op1_16 = IA32_READ_16BIT_REG(i->rm());
#if defined(IA32_HostAsm_And16)
    Bit32u flags32;
    asmAnd16(result_16, op1_16, op2_16, flags32);
    IA32_setEFlagsOSZAPC(flags32);
#else
    result_16 = op1_16 & op2_16;
#endif
    IA32_WRITE_16BIT_REG(i->rm(), result_16);
  }
  else 
  {
    read_RMW_virtual_word(i->seg(), IA32_RMAddr(i), &op1_16);
#if defined(IA32_HostAsm_And16)
    Bit32u flags32;
    asmAnd16(result_16, op1_16, op2_16, flags32);
    IA32_setEFlagsOSZAPC(flags32);
#else
    result_16 = op1_16 & op2_16;
#endif
    write_RMW_virtual_word(result_16);
  }
#if !defined(IA32_HostAsm_And16)
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);
#endif
}

void IA32_CPU::TEST_EwGw(Ia32_Instruction_c *i)
{
  Bit16u op2_16, op1_16;

  op2_16 = IA32_READ_16BIT_REG(i->nnn());
  if (i->modC0()) 
  {
    op1_16 = IA32_READ_16BIT_REG(i->rm());
  }
  else 
  {
    read_virtual_word(i->seg(), IA32_RMAddr(i), &op1_16);
  }
#if defined(IA32_HostAsm_Test16)
  Bit32u flags32;
  asmTest16(op1_16, op2_16, flags32);
  IA32_setEFlagsOSZAPC(flags32);
#else
  Bit16u result_16 = op1_16 & op2_16;
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);
#endif
}

void IA32_CPU::TEST_AXIw(Ia32_Instruction_c *i)
{
  Bit16u op2_16, op1_16;

  op1_16 = AX;
  op2_16 = i->Iw();
#if defined(IA32_HostAsm_Test16)
  Bit32u flags32;
  asmTest16(op1_16, op2_16, flags32);
  IA32_setEFlagsOSZAPC(flags32);
#else
  Bit16u result_16 = op1_16 & op2_16;
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);
#endif
}

void IA32_CPU::TEST_EwIw(Ia32_Instruction_c *i)
{
  Bit16u op2_16, op1_16;

  op2_16 = i->Iw();
  if (i->modC0()) 
  {
    op1_16 = IA32_READ_16BIT_REG(i->rm());
  }
  else 
  {
    read_virtual_word(i->seg(), IA32_RMAddr(i), &op1_16);
  }
#if defined(IA32_HostAsm_Test16)
  Bit32u flags32;
  asmTest16(op1_16, op2_16, flags32);
  IA32_setEFlagsOSZAPC(flags32);
#else
  Bit16u result_16 = op1_16 & op2_16;
  IA32_SET_FLAGS_OSZAPC_RESULT_16(result_16, IA32_INSTR_LOGIC16);
#endif
}
